package com.exonline.back.controller.course;

import cn.hutool.core.util.IdUtil;
import com.exonline.commons.base.IBaseServlet;
import com.exonline.commons.entity.Courses;
import com.exonline.commons.entity.Direction;
import com.exonline.commons.utils.SqlConditionBuilder;
import com.exonline.commons.utils.TokenUtils;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @desc 课程管理模块C层
 * @author hbrj
 */
@WebServlet("/admin/courses")
public class CoursesServlet extends HttpServlet implements IBaseServlet {
    private static final long serialVersionUID = 1L;

    // 使用Jackson库进行JSON格式的响应输出
    ObjectMapper mapper = new ObjectMapper();

    // 课程服务类，用于处理课程相关业务逻辑
    CoursesService service = new CoursesService();

    // 当前页码，默认第一页
    int pageno = 1;
    int pagesize = 4;
    /**
     * 处理客户端发来的HTTP请求，依据请求中的method参数，调用不同的操作方法。
     * 支持的操作有：查询课程、添加课程、编辑课程、删除课程、审核课程等。
     *
     * @param req  客户端请求
     * @param resp 服务端响应
     * @throws ServletException 如果请求处理过程中发生错误
     * @throws IOException 如果响应过程中发生I/O错误
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取分页参数，默认为1
        String pagenoStr = req.getParameter("pageno");
        if (pagenoStr != null) {
            pageno = Integer.parseInt(pagenoStr);
        }

        // 获取请求的方法类型
        String method = req.getParameter("method");
        try {
            // 根据方法名，执行不同的操作
            if ("queryall".equals(method)) {
                this.query(req, resp);
            } else if ("queryallreview".equals(method)) {
                this.queryallreview(req, resp);
            } else if ("structurequery".equals(method)) {
                this.structureQuery(req, resp);
            } else if ("queryone".equals(method)) {
                this.queryOne(req, resp);
            } else if ("doreview".equals(method)) {
                this.doReview(req, resp);
            } else if ("add".equals(method)) {
                this.add(req, resp);
            } else if ("edit".equals(method)) {
                this.edit(req, resp);
            } else if ("delete".equals(method)) {
                this.delete(req, resp);
            } else if ("deletereview".equals(method)) {
                this.deletereview(req, resp);
            } else if ("setstatus".equals(method)) {
                this.setStatus(req, resp);
            }
        } catch (Exception e) {
            // 如果发生异常，抛出ServletException
            throw new ServletException("课程操作出现错误,错误信息:" + e.getMessage(), e);
        }
    }
    /**
     * @desc 修改课程状态
     * @author hbrj
     */
    private void setStatus(HttpServletRequest req, HttpServletResponse resp) throws IOException, SQLException {
        String id = req.getParameter("id");
        String status = req.getParameter("status");
        service.update(status,id);
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("msg", "修改成功");
        map.put("data", id);
        mapper.writeValue(resp.getWriter(), map);
    }

    /**
     * @desc 查询课程审核内容以及课程审核历史记录
     * @param req  请求参数
     * @param resp 响应数据
     * @throws SQLException 如果数据库查询出错
     * @throws IOException 如果响应过程中发生I/O错误
     */
    private void queryallreview(HttpServletRequest req, HttpServletResponse resp) throws SQLException, IOException {
        String condition = SqlConditionBuilder.buildCourseCondition(req);
        List<Courses> courses = service.queryAllReviewHistory(condition, pagesize, pageno);
        String rowCount = service.getRowCount("SELECT distinct count(*) FROM courses c join teacher t on t.id = c.tid left join coursesreviewhistory co on co.cid = c.id WHERE "+condition);
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("msg", "查询成功");
        map.put("data", courses);
        map.put("rowCount", rowCount);
        mapper.writeValue(resp.getWriter(), map);
    }

    /**
     * @desc  删除课程审核记录
     * @param req  请求参数
     * @param resp 响应数据
     * @throws SQLException 如果数据库操作失败
     */
    private void deletereview(HttpServletRequest req, HttpServletResponse resp) throws SQLException, IOException {
        String id = req.getParameter("id");
        String status = req.getParameter("status");
        service.update(status, id);
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("msg", "删除成功");
        map.put("data", id);
        mapper.writeValue(resp.getWriter(), map);
    }

    /**
     * @desc 执行课程审核操作
     * @param req  请求参数
     * @param resp 响应数据
     */
    private void doReview(HttpServletRequest req, HttpServletResponse resp) {
        try {
            // 获取当前登录用户的ID和名称
            String aid = TokenUtils.getId(req);
            String aname = TokenUtils.getName(req);
            System.out.println("审核人id:" + aid + " 审核人名称:" + aname);
            String rowCount = service.getRowCount("SELECT COUNT(*) from courses");
            String status = req.getParameter("status");
            if (status != null) {

                String cid = req.getParameter("id");
                String comment = req.getParameter("comment");
                service.update(status, cid, comment, aid);

                Map<String, Object> map = new HashMap<>();
                map.put("code", 200);
                map.put("msg", "课程审核成功");
                map.put("data", cid);
                mapper.writeValue(resp.getWriter(), map);
            }
        } catch (RuntimeException | SQLException | IOException e) {
            // 如果缺少参数或发生异常，抛出运行时异常
            throw new RuntimeException("缺少指定参数,错误信息:" + e.getMessage(), e);
        }
    }

    /**
     * @desc 结构化查询课程
     * @param req  请求参数
     * @param resp 响应数据
     * @throws SQLException 如果数据库查询出错
     * @throws IOException 如果响应过程中发生I/O错误
     */
    private void structureQuery(HttpServletRequest req, HttpServletResponse resp) throws SQLException, IOException {
        String condition = req.getParameter("condition");
        List<Direction> directions = service.structurequery(condition, pagesize, pageno);
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("msg", "结构化查询成功");
        map.put("data", directions);
        mapper.writeValue(resp.getWriter(), map);
    }

    /**
     * @desc 查询所有课程
     * @param req  请求参数
     * @param resp 响应数据
     * @throws SQLException 如果数据库查询出错
     * @throws IOException 如果响应过程中发生I/O错误
     */
    @Override
    public void query(HttpServletRequest req, HttpServletResponse resp) throws SQLException, IOException {
        String condition = SqlConditionBuilder.buildCourseCondition(req);
        List<Courses> courses = service.queryAll(condition, pagesize, pageno);
        String rowCount = service.getRowCount("SELECT COUNT(*) from courses");
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("msg", "查询成功");
        map.put("data", courses);
        map.put("rowCount",rowCount);
        mapper.writeValue(resp.getWriter(), map);
    }

    /**
     * @desc 删除课程
     * @param req  请求参数
     * @param resp 响应数据
     * @throws SQLException 如果数据库删除操作失败
     * @throws IOException 如果响应过程中发生I/O错误
     */
    @Override
    public void delete(HttpServletRequest req, HttpServletResponse resp) throws SQLException, IOException {
        String id = req.getParameter("id");
        service.deleteById(id);
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("msg", "删除成功");
        map.put("data", id);
        mapper.writeValue(resp.getWriter(), map);
    }

    /**
     * @desc 查询单个课程
     * @param req  请求参数
     * @param resp 响应数据
     * @throws SQLException 如果数据库查询出错
     * @throws IOException 如果响应过程中发生I/O错误
     */
    @Override
    public void queryOne(HttpServletRequest req, HttpServletResponse resp) throws SQLException, IOException {
        String id = req.getParameter("id");
        Courses courses = service.queryOne(id);
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("msg", "查询成功");
        map.put("data", courses);
        mapper.writeValue(resp.getWriter(), map);
    }

    /**
     * @desc 编辑课程
     * @param req  请求参数
     * @param resp 响应数据
     * @throws SQLException 如果数据库操作失败
     * @throws IOException 如果响应过程中发生I/O错误
     */
    @Override
    public void edit(HttpServletRequest req, HttpServletResponse resp) throws SQLException, IOException {
        String id = req.getParameter("id");
        String tid = req.getParameter("tid");
        String level = req.getParameter("level");
        String name = req.getParameter("name");
        String introduce = req.getParameter("introduce");
        String price = req.getParameter("price");
        String direction = req.getParameter("direction");
        String subject = req.getParameter("subject");
        service.update(id, tid, level, name, introduce, price, direction, subject);
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("msg", "修改成功");
        map.put("data", id + ":" + name);
        mapper.writeValue(resp.getWriter(), map);
    }

    /**
     * @desc 添加课程
     * @param req  请求参数
     * @param resp 响应数据
     * @throws SQLException 如果数据库操作失败
     * @throws IOException 如果响应过程中发生I/O错误
     */
    @Override
    public void add(HttpServletRequest req, HttpServletResponse resp) throws SQLException, IOException {
        String id = IdUtil.simpleUUID();
        String tid = req.getParameter("tid");
        String level = req.getParameter("clevel");
        String name = req.getParameter("cname");
        String introduce = req.getParameter("cintroduce");
        String price = req.getParameter("cprice");
        String direction = req.getParameter("cdirection");
        String subject = req.getParameter("csubject");
        service.add(id, tid, level, name, introduce, price, direction, subject, 0, 1);
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("msg", "添加成功");
        map.put("data", name);
        mapper.writeValue(resp.getWriter(), map);
    }
}
